<template>
 <div>
  <el-dialog :visible.sync="isShow" style="" @open="handleOpen" @close="handleClose" title="注册用户" center>
    <el-form :model="form" :rules="rules" label-width="80px" style="width: 400px" ref="form" label-position="left">
      <el-form-item label="头像" prop="avatar">
        <uploadImage v-model.trim="form.avatar"></uploadImage>
      </el-form-item>

      <el-form-item label="昵称" prop="username">
        <el-input v-model.trim = "form.username"></el-input>
      </el-form-item>

      <el-form-item label="邮箱" prop="email">
        <el-input v-model.trim="form.email"></el-input>
      </el-form-item>

      <el-form-item label="手机" prop="phone">
        <el-input v-model.number.trim="form.phone" :disabled="phoneLocked"></el-input>
      </el-form-item>

      <el-form-item label="密码" prop="password">
        <el-input v-model.trim="form.password" @copy.native.capture.prevent @paste.native.capture.prevent show-password></el-input>
      </el-form-item>

      <el-form-item label="确认密码" prop="confirmPassword">
        <el-input v-model.trim="form.confirmPassword" ref="confirmPassword" @copy.native.capture.prevent @paste.native.capture.prevent :disabled="!form.password" show-password></el-input>
      </el-form-item>

      <el-form-item label="图形码" prop="rcode">
        <div style="display: flex; justify-content: space-between;">
          <el-input v-model.trim="form.rcode" style="width: 60%"  :disabled="(loadingCode || phoneLocked  && partcialPhoneLocked)"></el-input>
          <div style="width: 35%;object-fit: contain;" v-loading="loadingCode">
            <img src="" alt="" style="width: 100%; height: 100%;cursor: pointer;" @click="refreshCode" v-if="((!phoneLocked || !partcialPhoneLocked) && !tempCheck)" ref="code"/>
            <el-button v-if="(phoneLocked && partcialPhoneLocked)" ref="waitMarker" disabled>{{`(${time})秒后获取`}}</el-button>
            <el-button v-if="tempCheck" @click="(tempCheck = false); form.rcode =''" type="success" plain>获取图形码</el-button>
          </div>
        </div>
      </el-form-item>

      <el-form-item label="验证码" prop="verificationCode">
        <div style="display:flex; justify-content: space-between;" v-loading="loadingVerificationCode">
          <el-input v-model.trim="form.verificationCode" style="width: 60%" :placeholder="verificationHint" :disabled="!phoneLocked" ref="verification"></el-input>
          <el-button type="primary" plain  style="width: 35%" @click="getVerificationCode" :disabled="(phoneLocked && partcialPhoneLocked)">获取验证码</el-button>
        </div>
      </el-form-item>

      <el-form-item>
        <div style="display: flex; justify-content:space-around; padding-top: 5%">
          <el-button @click.native="confirmed" type="primary" style="width:40%;">注册用户</el-button>
          <el-button @click.native="canceled" style="width:40%">取消注册</el-button>
        </div>
      </el-form-item>

    </el-form>
  </el-dialog>
 </div>
</template>

<script>
import uploadImage from '@/components/uploadImage'
import { postSendsmsAPI, postRegisterAPI } from '@/api/register.js'
import {UserList} from '@/api/cyy'
// postRegisterAPI
import request from '@/utils/request'

export default {
  name: 'registerIndex',
  components: {
    uploadImage
  },
  data () {
    return {
      tempCheck: false, 
      // hasFormInput: false,
      time: 5,
      timeInterval: '',
      phoneLocked: false,
      partcialPhoneLocked: false,
      loadingCode: false,
      saveTempInfo: false,
      loadingVerificationCode: false,
      isShow: false, 
      verificationHint: '请先获取验证码',
      form: //this.getTempForm() ||
      {
        avatar: '', //none
        username: '', //chenfuduo
        email: '', //1747183517358@qq.com
        phone: '', //18118181811
        password: '', //12345678
        confirmPassword: '',
        rcode: '',
        verificationCode: ''
      },
      formChanged: {
        avatar: false, //none
        username: false, //chenfuduo
        email: false, //1747183517358@qq.com
        phone: false, //18118181811
      },
      rules: {
        avatar: [
          { required: true, message: '请输入头像', trigger: 'blur' }
        ],
        username: [
          { required: true, message: '请输入用户名', trigger: 'blur' },
          { min: 2, max: 10, message: '请输入2-10位用户名', trigger: ['change', 'blur'] }
        ],
        email: [
          { required: true, message: '请输入邮箱', trigger: 'blur' },
          {
            pattern: /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/,
            message: '邮箱格式错误',
            trigger: ['change', 'blur']
          }
        ],
        phone: [
          { required: true, message: '请输入电话号码', trigger: 'blur' },
          {
            validator: (rule, value, callback) => {
              return /^(0|86|17951)?(13[0-9]|15[012356789]|166|17[3678]|18[0-9]|14[57])[0-9]{8}$/.exec(value) ? callback() : callback(new Error('手机号码格式错误'))
            },
            trigger: ['change', 'blur']
          }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' },
          {
            validator: (rule, value, callback) => {
              this.$refs.form.validateField('confirmPassword')
              return value === this.form.confirmPassword?callback():callback()
            }
          }
        ],
        confirmPassword: [
          { required: true, message: '请输入确认密码', trigger: 'blur' },
          {
            validator: (rule, value, callback) => {
              if (!this.form.password) {
                this.form.confirmPassword = ''
                return callback()
              }
              return value === this.form.password?callback():callback(new Error('两次输入的密码不一致'))
            }
          }
        ],
        rcode: [
          { required: true, message: '请输入图形验证码', trigger: 'blur' },
          {
            validator: (rule, value, callback) => {
              return /^\d{4}$/.exec(value) ? callback() : callback(new Error('验证码格式错误'))
            },
            trigger: ['change', 'blur']
          }
        ],
        verificationCode: [
          { required: true, message: '请输入短信验证码', trigger: 'blur' }
        ]
      },
      
    }
  },
  created() {
    
  },
  methods: {
    async getVerificationCode() {
      if(this.phoneLocked && this.partcialPhoneLocked) return

      let phone = false
      let rcode = false

      this.$refs.form.validateField('phone', (callback) => {
        if (!callback) {
          // 自定义验证
          phone = true
          return true
        }
      })

      this.$refs.form.validateField('rcode', (callback) => {
        if (!callback) {
          // 自定义验证
          rcode = true
          return true
        }
      })

      // 验证全部通过 则 发送验证码信息
      if (phone && rcode) {
        this.loadingVerificationCode = true
        const res = await postSendsmsAPI({ code: this.form.rcode, phone: this.form.phone })
        this.loadingVerificationCode = false
        if (res.data.captcha) {

          // console.log('phone has locked')
          this.phoneLocked = true
          //
          this.verificationHint = ''
          this.$nextTick(() => this.$refs.verification.focus()) 
          //电话号码处理
          // 电话值锁定
          this.form.password = ''
          this.form.confirmPassword = ''
          sessionStorage.setItem('tempRegister_Info', JSON.stringify(this.form))
          this.$message.success('验证码为： ' + res.data.captcha)
          //防止老6
          this.refreshCode()

          
        //设置倒计时
          this.partcialPhoneLocked = true
          this.timeInterval = setInterval(() =>
          {
            this.time--
            if (this.time === 0) {
              this.time = 5
              clearInterval(this.timeInterval)
              this.partcialPhoneLocked = false
              this.tempCheck = true
            }
          }, 1000);
        } else {
          this.form.rcode = ''
          this.refreshCode()
          this.$message.error(res.message)
        }
      }
    },
    confirmed () {
      // 表单验证
      this.$refs.form.validate(async (v) => {
        if (v) {
          // 上传头像图片 获取图片URL
          // 上传注册信息  获取固定了的 电话值
          this.form.phone = (JSON.parse(sessionStorage.getItem('tempRegister_Info'))).phone || this.form.phone
          await postRegisterAPI(this.form)
          this.isShow = false
          this.$message.success('注册成功')
        }
      })
    },
    //电话号码处理
    /**
     * 如果用户在通过电话号码获取验证码之后，改变了表单上的电话号码，那么其信息会与后台冲突
     * 此时就需要 电话号码处理 
     *    将电话号码在获取验证码之后预存，再在需要调用电话号码时，使用预存的电话号码
     *    
     *    在本组件中，电话号码预存在 sessionStorage 里, 但是sessionStorage可以手动更改，因此实际应用中不可行
     * 
     *    在实际应用中，可以给本地一个临时token，将临时token和电话号码在后台进行绑定并预存在后台数据库 {临时token：电话号码}
     *      在 需要调用电话号码时，则使用临时token向后台发送请求，获取该临时token对应的电话号码
     *      在 取消注册 并 取消保存信息 时，则使用临时token向后台发送请求，删除该临时token以及其对应的电话号码，并清空临时token在本地的存储
     * 
     *      该临时token会在短时间内失效，并删除其对应数据
     *      
     *      若 用户 手动更改 临时token 则会请求失败
     *      若 token 被盗取 其时效性也能防止用户信息泄露
     * 
     *    
     */
    canceled() {
      // if (this.hasFormInput) {
      if(this.formChanged.avatar || this.formChanged.username || this.formChanged.email || this.formChanged.phone){
        this.$confirm('需要保留注册信息吗？')
          .then(() => {
            this.saveTempInfo = true
            //电话号码处理
            if (sessionStorage.getItem('tempRegister_Info')) {
              this.form.phone = (JSON.parse(sessionStorage.getItem('tempRegister_Info'))).phone
            }
            // 不可预存项
            this.form.password = ''
            this.form.confirmPassword = ''
            this.form.rcode = ''
            this.form.verificationCode = ''
            sessionStorage.setItem('tempRegister_Info', JSON.stringify(this.form))
            this.isShow=false
          }).catch(() => {  
            this.saveTempInfo = false
            this.isShow=false
          })

      } else {
        this.isShow = false
      }
    },
    handleOpen() {
      this.form = JSON.parse(sessionStorage.getItem('tempRegister_Info')) || this.form
      sessionStorage.removeItem('tempRegister_Info')
      this.form.rcode = ''
      this.form.verificationCode = ''
      // this.hasFormInput = false
    },
    handleClose () {
      this.form = {
        avatar: '',
        username: '',
        email: '',
        phone: '',
        password: '',
        rcode: '',
        verificationCode: ''
      }
      this.$refs.form.resetFields()
      this.phoneLocked = false
      if(!this.saveTempInfo) sessionStorage.removeItem('tempRegister_Info')
    },
    // 刷新验证码
    async refreshCode() {
      if(!this.phoneLocked || !this.partcialPhoneLocked){
        this.loadingCode = true

        this.$nextTick(()=>{
          this.$refs.code.src = process.env.VUE_APP_BASE_URL + '/captcha?type=sendsms'
        })


        this.loadingCode = false

        
      }
    }
    
  },
  watch: {
    // form: {
    //   deep: true,
    //   handler() {
    //     this.hasFormInput = true
    //   }
    //   // ,
    //   // immediate: true
    // }
    'form.avatar': {
      handler(newVal, oldVal){
        if (!newVal) {
          this.formChanged.avatar = false
          return false
        }
        this.formChanged.avatar = newVal !== oldVal
        return newVal !== oldVal
      }
    },
    'form.username': {
      handler(newVal, oldVal){
        if (!newVal) {
          this.formChanged.username = false
          return false
        }
        this.formChanged.username = newVal !== oldVal
        return newVal !== oldVal
      }
    },
    'form.email': {
      handler(newVal, oldVal){
        if (!newVal) {
          this.formChanged.email = false
          return false
        }
        this.formChanged.email = newVal !== oldVal
        return newVal !== oldVal
      }
    },
    'form.phone': {
      handler(newVal, oldVal){
        if (!newVal) {
          this.formChanged.phone = false
          return false
        }
        this.formChanged.phone = newVal !== oldVal
        return newVal !== oldVal
      }
    }
  }
}
</script>

<style lang="scss" scoped>

::v-deep .el-dialog{
  width: 500px;
  .el-dialog__header{
    background: #5bb5ff;//linear-gradient(#1493fa 10%, #01c6fa 96%);
    .el-dialog__title{
      color: #395f7e;
    }
  }
  .el-dialog__body{
    background: #52d9ff80;
    .el-form-item__label{
      color: #395f7e;
    }
  }
  //#01c6fa
  .el-input__inner{
    background: #cbf4ff;
  }
  .el-icon-plus{
    background: #cbf4ff;
  }
}

</style>
